Bom 和 Ajax

【金山文档】 Bom和Ajax

https://kdocs.cn/l/cnWuvzdJqqOU

(一) window对象

JavaScript运行在浏览器, 而window对象是浏览器提供的一个对象, 所以也可以称为宿主对象。window包含Dom和Bom和其它的一些全局对象和方法, EcmaScript则是运行在浏览器上, window为EcmaScript提供了全局作用域.

(1) 浏览器缓存

问题1: 浏览器本地缓存有哪些

问题2: cookie、sessionStorage、localStorage有什么区别

相同点:

cookie,sessionStorage,localStorage都是存放在客户端(浏览器端),都是浏览器缓存

不同点:

  1. 作用不一样

    cookie数据始终在同源的http请求中携带,在浏览器和服务器来回传递,而sessionStorage,localStorage仅在本地(l浏览器)保存

  2. 大小限制区别

    cookie数据不超过4kb,sessionStorage和localStorage最大为5M, sessionStorage和localStorage是html5新特性

  3. 数据有效期不同

    • cookie在设置的(服务器设置)有效期内有效,不管窗口和浏览器关闭
    • sessionStorage仅在当前浏览器窗口关闭前有效,关闭即销毁(临时存储)
    • localStorage始终有效,用于持久化的本地存储,除非主动删除数据,否则不会过期
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <script>
    // sessionStorage存数据
    sessionStorage.setItem('username','张三');
    sessionStorage.setItem('age',18);

    // sessionStorage取数据
    var username = sessionStorage.getItem('username');
    console.log(username);
    var age = sessionStorage.getItem('age');
    console.log(age); 
    // 清除
    sessionStorage.removeItem('username');


    // localStorage存数据
    localStorage.setItem("username","李四");
    // localStorage取数据
    var username = localStorage.getItem('username');
    console.log(username);
    // 全部清除
    localStorage.clear();
  </script>
</body>
</html>

api总结:

  1. 存数据 setItem('名称', 值);
  2. 取数据 getItem('名称');
  3. 移除数据 removeItem('名称');
  4. 全部清除 clear();

注意:

  1. 数据存入缓存都变成了字符串
  2. 需要存对象的时, 需要先将对象转成json字符串

(2) window的一些方法

  1. JSON

    • JSON数据格式

    • JSON.stringfy()

    • JSON.parse();

  2. open();

  3. eval(); // 略

  4. parseInt() 和 parseFloat(); // 略

  5. encodeURI() 和 decodeURI();

  6. setTimout() 和clearTimeout();

  7. setInterval() 和 clearInterval();

01 JSON

1. json数据格式

json数据是一种轻量级的数据格式, 非常方便在互联网上传输, 它的格式如下:

  1. 一般是对象或者数组, 服务器端返回给前端的一般就是这种数据格式
  2. 以键值对存储,键名必须是双引号, 值如果是字符串也必须是双引号, 最后一个键值对不能加逗号(普通对象可以加)
[
    {
        "username": "张三",
        "age": 18
    },
    {
        "username": "张三2",
        "age": 18
    },
    {
        "username": "张三3",
        "age": 18
    }
]
2. 对象和json字符串互转
var obj = {username: '张三', age: 18};
// 对象转json字符串
var str = JSON.stringify(obj);
typeof str; // string

// str2是个符合json数据格式的字符串
var str2 = '{"username":"张三","age":18}';
// json字符串转对象
var obj2 = JSON.parse(str2);
typeof obj2;  // object
3. JSON应用

localStorage和sessionStorage无法存对象, 能存字符串, 所以我们想存放对象, 可以先将对象转成字符串, 需要使用的时候, 再讲字符串转成对象, 举例: 将张三对象存取

var person = {username:'张三', age:18};
// 1.将对象转成json字符串
var str = JSON.stringfy(person);
// 2.将字符串存入缓存
localStorage.setItem('person',str);

/* 获取数据 */
// 1.将数据取出
var person =localStorage.getItem('person');
// 2.将字符串person转成对象
person = JSON.parse(person);
console.log(person);

02 window的其它方法

// 打开一个窗口
window.open('http://www.baidu.com');
// 将url编码
var url = 'http://huruqing.cn:3003?username=张三&age=18";
var newUrl = encodeURI(url);
// 解码
var newUrl = decodeURI(newUrl);

// 延迟执行
var timer = setTimeout(function(){
    alert(2222);
}, 3000);
// 清除延迟器
clearTimeout(timer);

// 定时器
var count = 60;
var timer = setInterval(function() {
    console.log(--count);
    if (count === 0) {
        // 清除定时器
		clearInterval(timer);
	}
},1000);

(二) BOM是什么

浏览器对象模型(Browser Object Model)简称 BOM, 浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器"对话"。

BOM对象包含了以下内容:

  1. location:包含当前网页文档的 URL 信息。
  2. history:包含浏览器窗口访问过的 URL 信息。
  3. navigator:包含客户端有关浏览器信息。
  4. screen:包含客户端屏幕的信息。
  5. frames: 返回窗口中所有命名的框架。
  6. XMLHttpRequest: 用来创建ajax对象的构造函数

1. location

包含当前网页文档的 URL 信息。

2. history

包含浏览器窗口访问过的 URL 信息。

  • history.back(); // 后退
  • history.forward(); // 前进
  • history.go(); // go(1)前进一个记录, go(-1)后退一个记录

3.navigator

包含客户端有关浏览器信息。主要用到的是navigator.userAgent

// 判断用户使用的设备是pc还是移动端,可以使用|添加更多设备类型
if(navigator.userAgent.match(/Android|iPhone|iPad/i)) {
    window.location.href = "移动端网站";
} else {
    window.location.href = "pc端网站";
}

(三) Ajax

Ajax知识点

ajax相关知识

  1. json数据格式
  2. JSON对象

ajax知识点

  1. 什么是ajax?
  2. 创建一个ajax的过程
  3. 查看网络请求
  4. get请求和post请求区别
  5. http状态码
  6. 跨域请求

json数据格式

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。

  1. json数据格式:

    • 属性必须是双引号(不能省略不能是单引号), 字符串的值也必须是双引号
    • 最后一个属性值不能加逗号(对象是可以加的)
    [
      {
        "username":"张三",
        "age":18
      },
      {
        "username":"李四",
        "age":18
      },
      {
        "username":"王五",
        "age":18
      }
    ]
    
  2. window提供JSON对象用于对json数据和对象互转

    var list = [
      {
        username: "张三",
        age: 18,
      },
      {
        username: "李四",
        age: 18,
      },
      {
        username: "王五",
        age: 18,
      },
    ];
    // 得到一个json字符串
    var str = JSON.stringify(list);
    console.log('str',typeof str);
    
    // 得到一个数组
    // 注:str必须是符合json格式的字符串才能转对象
    var newList = JSON.parse(str);
    console.log('newList',typeof newList);
    

1. 什么是ajax?

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

在没有ajax之前, 更新页面需要重新加载整个页面, 填一个表单, 然后提交, 如果失败了, 重新提交需要重新填写整个表单

2. ajax创建过程

概念: 接口接口地址, 接口是服务器给前端提供数据的出口, 接口地址, 就是接口所在的位置

前端可以使用ajax请求接口从而获得服务器提供的数据, 以下是请求数据的全过程(步骤)

  1. 创建异步ajax请求对象

  2. 设置请求的参数

    • 请求方法 get或post
    • 请求参数
  3. 发送请求

  4. 注册(绑定)事件

  5. 获取返回数据

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <script>
        // 创建异步ajax请求对象
        var xhr = new XMLHttpRequest();
        // 设置请求方法和请求参数
        xhr.open('get','http://huruqing.cn:3009/getUsers');
        // 发送请求
        xhr.send();
        // 注册(绑定)事件
        xhr.onreadystatechange = function() {
          if (xhr.readyState === 4 && xhr.status === 200) {
            // 服务器返回的一般是json数据
            console.log(typeof xhr.responseText);
            // 将json数据变成对象或者数组
            let list = JSON.parse(xhr.responseText);
            console.log(list);
            // 将数据展示到页面上.....
          }
        }
      </script>
    </body>
    </html>
    

    // 请求方法和请求参数

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    
    <body>
      <script>
        // get请求
        function getData(userId) {
          var xhr = new XMLHttpRequest();
          xhr.open('get', 'http://huruqing.cn:3009/getUserDetail?userId='+userId);
          xhr.send();
          xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
              let obj = JSON.parse(xhr.responseText);
              document.write(obj.username + '<br/>');
            }
          }
        }
        getData('f7193f56cf2f3c'); 
    
    
        // post请求
        function postData(userId) {
          var xhr = new XMLHttpRequest();
          xhr.open('post', 'http://huruqing.cn:3009/getUserDetail');
          xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
          xhr.send('userId='+userId);
          xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
              let obj = JSON.parse(xhr.responseText);
              console.log(obj);
              document.write(obj.username + '<br/>');
            }
          }
        }
        postData('f7193f56cf2f3c');  
      </script>
    </body>
    </html>
    

3. 查看网络请求

  1. 认识浏览器控制台

    1. 元素
    2. 控制台
    3. 来源: 源代码
    4. 网络: 查看网络请求
    5. 其它....

    image-20220103125116392

  2. 网络一栏

    1. http请求: 一个图片, 一个css文件, 一个js文件这些都是从服务器端取回来的, 都叫一个http请求, XHR请求就是ajax请求了
    2. 过滤: 搜索某个网络请求
    3. 双击一个xhr请求, 就能查看到请求的详细信息
  3. ajax请求详解

    1. 请求消息
      • 常规消息
      • 请求头
      • 响应头
    2. 载荷: 请求参数
    3. 预览: 服务器返回数据预览
    4. 响应: 服务器返回的数据
    5. 其它...

    image-20220103125720199

4. get请求和post区别

  1. 用途不一样

    • get 一般用于获取数据: 数据事先存在服务器, 通过get请求去获取
    • post 一般用于发送数据: 比如用户注册, 用户填好表单后, 通过post把数据传给服务器, 服务器再将数据存入数据库

    ps: 实际项目中, 也并非一定要这么做, 具体情况根据公司实际情况处理, 后台一般会提供接口文档, 指定请求方法

  2. 传递参数方式不一样

    • get请求如果需要传递参数,那么会默认将参数拼接到url的后面;然后发送给服务器;get请求传递参数大小是有限制的;是浏览器的地址栏有大小限制;
    • post传递参数,需要把参数放进请求体中,发送给服务器;post请求参数放进了请求体中,对大小没有要求;
  3. 安全性问题

    • get安全性相对较低
    • post安全性相对比较高;

    ps: 安全性是相对而言的, 网页的安全性其实不管用那种方式, 安全性都很难很高, 因为别人甚至可以绕过浏览器去请求数据, 所以在实际项目中, 一般前端要校验数据, 后端也要校验数据

  4. 浏览器缓存

    • get 一般会走缓存,为了防止走缓存,给url后面每次拼的参数不同;放在?后面,一般用个时间戳
    • post请求不会走缓存;

5. http状态码

上面代码中的 xhr.readyState === 4 && xhr.status 含义

XHR.readyState (了解)

当发送一个请求后,客户端需要确定这个请求什么时候会完成,因此,XMLHttpRequest对象提供了onreadystatechange事件机制来捕获请求的状态,继而实现响应。

XHR.readyState 请求就绪状态(0,1,2,3,4),而且状态也是不可逆的:

0:请求未初始化,还没有调用 open()。

1:请求已经建立,但是还没有发送,还没有调用 send()。

2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。

3:请求在处理中;通常响应中已有部分数据可用了,没有全部完成。

4:响应已完成;您可以获取并使用服务器的响应了。

xhr.status 就是http状态码了

https://www.runoob.com/http/http-status-codes.html

重点几个:

200 请求成功。一般用于GET与POST请求

301 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

302 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI。301和302都叫地址重定向, 一个是永久重定向, 一个是临时重定向

304 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

403 服务器理解请求客户端的请求,但是拒绝执行此请求

404 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面

405 客户端请求中的方法被禁止

500 服务器内部错误,无法完成请求

6. 跨域请求

1. 跨域请求相关知识

什么叫跨域,浏览器有同源策略,只有当“协议”、“域名”、“端口号”都相同时,才能称之为是同源,其中有一个不同,即是跨域。

同源策略的作用是什么呢?同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

那么我们又为什么需要跨域呢?一是前端和服务器分开部署,接口请求需要跨域,二是我们可能会加载其它网站的页面作为iframe内嵌。

跨域的方法有哪些?

  1. jsonp跨域

  2. cors跨域

    jsonp 只能支持 get 请求,cors 可以支持多种请求。cors 并不需要前端做什么工作。

  3. proxy(代理)跨域

    • nginx 反向代理(运营或后台)
    • webpack设置proxy跨域(前端)
  4. websocket跨域

  5. postMessage

  6. 其它方式跨域

    • window.name + iframe
    • location.hash + iframe
    • document.domain

2. jsonp跨域

问题1: 问什么说jsonp不算真正的ajax?

  1. ajax的核心是通过xmlHttpRequest获取非本页内容 jsonp的核心是动态添加script标签调用服务器提供的js脚本
  2. jsonp只支持get请求,ajax支持get和post请求

问题2: jsonp跨域原理是什么?

尽管浏览器有同源策略,但是 <script> 标签的 src 属性不会被同源策略所约束,可以获取任意服务器上的脚本并执行。jsonp 通过插入script标签的方式来实现跨域,参数只能通过url传入,仅能支持get请求。

json跨域步骤:

方式一:

  1. 创建用户接收数据的方法,比如getData
  2. 添加script标签, src地址指向了jsonp接口地址,带上参数callback=getData
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    function getData(data) {
      console.log(data);
    }
  </script>
  <script src="http://huruqing.cn:3009/getData?callback=getData"></script>
</body>
</html>

方式二:

使用动态创建script的方式

  1. 创建用户接收数据的方法,比如getData

  2. 动态插入script标签

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    function getData(data) {
      console.log(data);
    }

    var script = document.createElement('script');
    script.src = 'http://huruqing.cn:3009/getData?callback=getData';
    document.body.appendChild(script);
  </script>
</body>
</html>

(四) 同步和异步

1. 同步和异步是什么

同步: 同一时间只做一件事, 做完一件事之后才开始做下一件事

异步: 同一时间做多件事

拿做一顿饭举例:

方案1:

  1. 第一步: 先做饭, 然后坐等饭煮熟
  2. 第二步: 开始洗菜, 洗锅, 然后开始炒菜
  3. 第三步: 饭菜上桌开始吃饭

方案2:

  1. 第一步: 做饭, 做饭的同时开始洗菜, 洗锅, 炒菜
  2. 第二步: 饭熟, 菜也熟了, 上桌吃饭

方案1就是同步

缺点: 速度慢, 优点: 调理清晰

方案2就是异步

缺点: 同时做多件事, 容易乱, 比如一个大厨同时炒几个菜, 经验不足容易手忙脚乱

优点: 效率高

2. js中的同步和异步

  1. setTimeout

    // 代码从上到下执行, 若是同步则打印1-2-3,但实际是打印1-3-2
    console.log(1);
    setTimeout(function() {
      console.log(2);
      console.log('时间到')
    },0)
    console.log(3);
    
  2. ajax请求

    • ajax默认是异步请求, 所以data的值为undefined, 因为程序并不会等待ajax请求完成才继续往下执行, 而是一边请求一边往下执行
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <script>
        var data;
        var xhr = new XMLHttpRequest();
        xhr.open('get','http://huruqing.cn:3009/getUsers');
        xhr.send();
        xhr.onreadystatechange = function() {
          if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(typeof xhr.responseText);
            data = JSON.parse(xhr.responseText); 
          }
        }
        console.log('data',data);
      </script>
    </body>
    </html>
    
    • ajax也可设置为同步请求

      open的第三个参数设置为true, 则ajax请求是异步, 默认为false(同步请求)

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <script>
        var data;
        var xhr = new XMLHttpRequest();
        xhr.open('get','http://huruqing.cn:3009/getUsers',true);
        xhr.send();
        xhr.onreadystatechange = function() {
          if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(typeof xhr.responseText);
            data = JSON.parse(xhr.responseText); 
          }
        }
        console.log('data',data);
      </script>
    </body>
    </html>
    

(五) 封装ajax请求的库

  1. jQuery.js封装有请求ajax的方法

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
    
      <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
      <script>
         $.ajax({
           type: 'get',
           data: {
            userId: '92be12aba9b01f'
           },
           url: 'http://huruqing.cn:3009/getUserDetail?userId',
           dataType: 'json',
           success: function(res) {
            console.log('res',res);
           }, 
           error: function(err) {
             console.log('err',err);
           }
         })
      </script>
    </body>
    </html>
    
  2. axios一个只封装了ajax请求的库, 目前最流行

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
    
      <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.24.0/axios.min.js"></script>
      <script>
        // get请求
        axios.get('http://huruqing.cn:3009/getUserDetail',{params: {userId: '92be12aba9b01f'}}).then(function (res) {
          console.log(res.data);
        })
        
        // post请求
        axios.post('http://huruqing.cn:3009/getUserDetail',{userId: '92be12aba9b01f'}).then(function (res) {
          console.log(res.data);
        })
      </script>
    </body>
    </html>
    

(六) 作业

1. 登录定时器

2. 使用js完成打卡

3. 完成影院列表